# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.conf import settings
# urllib python内置的标准模块，用于发送http请求，类似vue里面的axios
from urllib.parse import urlencode
from urllib.request import urlopen
import json

class CaptchaAPIView(APIView):
    """验证码"""
    def get(self,request):
        """接受客户端提交的验证码相关信息"""
        params = {
            "aid": settings.TENCENT_CAPTCHA.get("APPID"),
            "AppSecretKey": settings.TENCENT_CAPTCHA.get("App_Secret_Key"),
            "Ticket": request.query_params.get("ticket"),
            "Randstr": request.query_params.get("randstr"),
            # request._request表示获取django框架的request对象
            # request._request.META获取本次客户端的请求头
            "UserIP": request._request.META.get("REMOTE_ADDR")
        }
        # 把字典数据转换成地址栏的查询字符串格式
        # aid=xxx&AppSecretKey=xxx&xxxxx
        params = urlencode(params)
        url = settings.TENCENT_CAPTCHA.get("GATEWAY")
        # 发送http的get请求
        # urlopen(url=请求地址，data=请求体数据)
        # 如果get请求，只需要填写参数1
        # 如果post请求，则需要填写参数1和参数2，其中参数2的格式为字典格式
        # urlopen是一个资源对象
        f = urlopen("%s?%s" % (url, params))
        # https://ssl.captcha.qq.com/ticket/verify?aid=xxx&AppSecretKey=xxx&xxxxx

        # f.read() 读取响应信息
        content = f.read()
        res = json.loads(content)
        if int(res.get("response")) == 1:
            # 验证成功
            return Response({"detail":1})
        else:
            # 验证失败
            return Response({"detail":0}, status=status.HTTP_400_BAD_REQUEST)

from rest_framework.generics import CreateAPIView
from .models import User
from .serializers import UserModelSerializer
class UserAPIView(CreateAPIView):
    """用户信息"""
    queryset = User.objects.all()
    serializer_class = UserModelSerializer

import random,json
from django_redis import get_redis_connection
import logging
logger = logging.getLogger("django")
from django.conf import settings
from renranapi.settings import constants
from mycelery.sms.tasks import send_sms

class SMSAPIView(APIView):
    """
    短信api接口
    /users/sms/(?P<mobile>1[3-9]\d{9})/
    """
    def get(self,request,mobile):
        """发送短信"""
        redis_conn = get_redis_connection("sms_code")
        # 1. 限制用户60s内只能发送一条短信[基于redis中的字符串有效期来完成]
        ret = redis_conn.get("interval_%s" % mobile)
        if ret is not None:
            # 如果ret有值,则表示60s内用户曾经发送短信,不能让用户频繁发送
            return Response({"detail":"对不起, 发送短信过于频繁!"})

        # 2. 生成6位随机验证码
        sms_code = "%06d" % ( random.randint(1,999999) )

        # 3. 保存验证码和手机到redis中
        # 3.1 初始化管道对象
        pipe = redis_conn.pipeline()
        # 3.2 开启事务
        pipe.multi()
        # 3.3 添加本次事务相关的命令到管道对象中,注意,管道中的命令不会被自动执行
        pipe.setex("sms_%s" % mobile, constants.SMS_EXPIRE_TIME, sms_code)
        pipe.setex("interval_%s" % mobile, constants.SMS_INTERVAL_TIME, "_")
        # 3.4 执行管道中所有命令,也就是事务提交
        pipe.execute() # 上面所有的命令都被一次性执行,要么一起成功,要么一起失败!

        # 异步发送短信
        send_sms.delay(mobile=mobile,sms_code=sms_code)

        # 返回响应信息
        return Response({"detail":"短信已发送!请留意您的手机短信!"})

from .models import User
class MobileAPIView(APIView):
    def get(self,request,mobile):
        try:
            User.objects.get(mobile=mobile)
            return Response({"detail":"当前手机号码已经被注册"}, status=status.HTTP_400_BAD_REQUEST)
        except User.DoesNotExist:
            return Response({"detail":"ok"})

import re
from django.core.mail import send_mail
from django.conf import settings
from itsdangerous import TimedJSONWebSignatureSerializer,BadData

class FindPasswordAPIView(APIView):
    def get(self,request):
        """发送邮件"""
        email = request.query_params.get("email")
        # 验证邮件  xx@xx.xxx
        if not re.match("^\w+@\w+\.\w+$",email):
            return Response({"detail":"邮箱格式不正确!"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return Response({"detail": "邮箱没有被注册,请重新确认!"}, status=status.HTTP_400_BAD_REQUEST)

        # 使用itsdangerous对链接中的数据进行加密
        serializer = TimedJSONWebSignatureSerializer(secret_key=settings.SECRET_KEY, expires_in=constants.EMAIL_EXPIRE_TIME)
        token = serializer.dumps({"email": email}).decode()
        url = settings.CLIENT_HOST + "/reset_password?token=%s" % token

        # 发送邮件
        send_mail(subject="【荏苒】找回密码",message="",html_message='尊敬的%s,您好!<br><br>您在荏苒网申请了找回密码, 请点击<a href="%s" target="_blank">重置密码</a>进行密码修改操作.<br><br>如果不是您本人的操作,请忽略本次邮件!' % (user.username,url),from_email=settings.EMAIL_FROM, recipient_list=[email])

        return Response({"detail":"ok"})

class CheckTokenAPIView(APIView):
    def get(self,request):
        token_string = request.query_params.get("token")
        serializer = TimedJSONWebSignatureSerializer(secret_key=settings.SECRET_KEY,
                                                     expires_in=constants.EMAIL_EXPIRE_TIME)
        try:
            token = serializer.loads(token_string)
        except BadData:
            return Response({"detail":"对不起,当前链接地址不存在或者已过期!"}, status=status.HTTP_400_BAD_REQUEST)

        return Response({"email": token.get("email")})


class ResetPasswordAPIView(APIView):
    def put(self,request):
        token_string = request.query_params.get("token")
        serializer = TimedJSONWebSignatureSerializer(secret_key=settings.SECRET_KEY,
                                                     expires_in=constants.EMAIL_EXPIRE_TIME)
        try:
            token = serializer.loads(token_string)
        except BadData:
            return Response({"detail": "对不起,当前链接地址不存在或者已过期!"}, status=status.HTTP_400_BAD_REQUEST)

        password = request.data.get("password")
        password2 = request.data.get("password2")

        if password != password2:
            return Response({"detail":"密码和确认密码不一致!"}, status=status.HTTP_400_BAD_REQUEST)

        user = User.objects.get(email=token.get("email"))
        user.set_password(password)
        user.save()

        return Response({"detail":"修改密码成功!"})